package com.star.common.core.domain;

import com.star.common.core.constant.Constants;
import com.star.common.core.entity.BaseR;
import com.star.common.core.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.Objects;

/**
 * 统一接口响应，标准的响应数据结构
 *
 * @author zhouhengzhe #公众号：小白的Java进阶之路
 */
@Data
@ApiModel("统一响应体")
public class R<T> implements BaseR {
    private static final long serialVersionUID = 1L;

    /**
     * 成功
     */
    public static final int SUCCESS = Constants.SUCCESS;

    /**
     * 失败
     */
    public static final int FAIL = Constants.FAIL;

    @ApiModelProperty("编码：0/200、请求成功；500、请求成功但服务异常；403、未登录或者token已失效；401、已登录没有权限。")
    private Integer code;

    @ApiModelProperty("返回信息")
    private String msg;

    @ApiModelProperty("响应数据")
    private T data;

    public R() {
        this(ResultCodeEnum.OK.getCode(), ResultCodeEnum.OK.getDesc());
    }

    public R(Integer code, String msg) {
        this(code, msg, null);
    }

    public R(T data) {
        this(ResultCodeEnum.OK.getCode(), ResultCodeEnum.OK.getDesc(), data);
    }

    public R(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> R<T> ok() {
        return new R<>();
    }

    public static <T> R<T> ok(T payload) {
        return new R(payload);
    }

    public static <T> R<T> ok(String msg, T data) {
        return new R(ResultCodeEnum.OK.getCode(), msg, data);
    }

    public static <T> R<T> fail(Integer code, String msg) {
        return new R(code, msg);
    }

    public static <T> R<T> fail(Integer code, String msg, T data) {
        return new R(code, msg, data);
    }

    public static <T> R<T> fail() {
        return fail(ResultCodeEnum.FAIL.getCode());
    }

    public static <T> R<T> fail(Integer code) {
        return fail(code, ResultCodeEnum.FAIL.getDesc());
    }

    public static <T> R<T> fail(String msg) {
        return fail(ResultCodeEnum.FAIL.getCode(), msg);
    }

    public static boolean empty(R<?> r) {
        return Objects.isNull(r) || !Objects.equals(r.getCode(), ResultCodeEnum.OK.getCode()) || Objects.isNull(r.getData());
    }

    public static <T> R<T> transform(R source) {
        R<T> target = new R();
        target.setCode(source.getCode());
        target.setMsg(source.getMsg());
        return target;
    }
    /**
     * 是否返回成功
     *
     * @return true/false
     */
    @Override
    public Boolean isOk() {
        return Objects.equals(this.getCode(), ResultCodeEnum.OK.getCode()) || Objects.equals(this.getCode(), 200);
    }
}
